package com.mixsmart.commonweb.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mixsmart.commonweb.IWebConstant;
import com.mixsmart.commonweb.bean.entity.TCOrg;
import com.mixsmart.commonweb.dao.PKStringDao;
import com.mixsmart.spellsql.utils.Cnd;
import com.mixsmart.spellsql.utils.Exp;
import com.mixsmart.utils.CollectionUtils;
import com.mixsmart.utils.StringUtils;

/**
 * 组织机构服务实现类
 * @author lmq
 * @version 1.0
 * @since JDK版本大于等于1.6
 * 2016年2月1日
 */
@Service
public class OrgService extends TreeService<TCOrg> {

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public boolean save(TCOrg org) {
		boolean is = false;
		if(null != org) {
			//判断父节点是否为空，如果为空，则表示节点没有具体的父节点，默认设置为属性结构的根节点
			org.setParentId(StringUtils.isEmpty(org.getParentId())?IWebConstant.TREE_ROOT_ID:org.getParentId());
			TCOrg parentOrg = getParent(org.getParentId());
			org.setLevel(super.getLevel(parentOrg));
			if(null != parentOrg) {
				org.setSerialName(parentOrg.getSerialName()+IWebConstant.SERVIAL_NAME_SPLIT+org.getName());
				org.setSerialCode(parentOrg.getSerialCode()+org.getId()+IWebConstant.SERVIAL_CODE_SPLIT);
			} else {
				org.setSerialName(org.getName());
				org.setSerialCode(org.getId()+IWebConstant.SERVIAL_CODE_SPLIT);
			}
			if(super.save(org)) {
				//如果父节点为叶子节点时，更新为非叶子节点
				if(null != parentOrg && parentOrg.getIsLeaf()) {
					parentOrg.setIsLeaf(false);
					super.update(parentOrg);
				}
			}
			is = true;
		}
		return is;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
	public boolean update(TCOrg org) {
		boolean is = false;
		if(null != org ) {
			//判断父节点是否为空，如果为空，则表示节点没有具体的父节点，默认设置为树形结构的根节点
			org.setParentId(StringUtils.isEmpty(org.getParentId())?IWebConstant.TREE_ROOT_ID:org.getParentId());
			TCOrg parentOrg = getParent(org.getParentId());
			org.setLevel(getLevel(parentOrg));
			if(null != parentOrg) {
				org.setSerialName(parentOrg.getSerialName()+IWebConstant.SERVIAL_NAME_SPLIT+org.getName());
				org.setSerialCode(parentOrg.getSerialCode()+org.getId()+IWebConstant.SERVIAL_CODE_SPLIT);
			} else {
				org.setSerialName(org.getName());
				org.setSerialCode(org.getId()+IWebConstant.SERVIAL_CODE_SPLIT);
			}
			TCOrg oldOrg = super.find(org.getId());
			if(null != oldOrg) {
				if(!org.getParentId().equals(oldOrg.getParentId())) {
					TCOrg oldParentOrg = getParent(oldOrg.getParentId());
					if(null != oldParentOrg) {
						if(this.getChildNum(oldParentOrg.getId())<2) {
							oldParentOrg.setIsLeaf(true);
						} else {
							oldParentOrg = null;
						}
					}
					oldOrg.assertValue(org);
					if(super.update(oldOrg)) {
						//如果当前父节点以前为叶子节点，则更新为非叶子节点
						if(null != parentOrg && parentOrg.getIsLeaf()) {
							parentOrg.setIsLeaf(false);
							super.update(parentOrg);
						}
						//如果以前的父节点只有一个叶子节点时,则更新为叶子节点
						if(null != oldParentOrg) {
							super.update(oldParentOrg);
						}
						//如果当前节点是父节点(非叶子节点)时，则更新子节点的level等级
						if(!oldOrg.getIsLeaf()) {
							ArrayList<TCOrg> childs = new ArrayList<TCOrg>();
							Map<String, TCOrg> mapOrg = new HashMap<String, TCOrg>();
							mapOrg.put(oldOrg.getId(), oldOrg);
							getCascadeChilds(childs, new String[]{oldOrg.getId()}, mapOrg);
							if(CollectionUtils.isNotEmpty(childs)) {
								//批量更新子节点对象
								super.update(childs);
							}
						}
						is = true;
					}//if
				} else {
					oldOrg.assertValue(org);
					is = super.update(oldOrg);
				}
			}//if
		}
		return is;
	}
	
	/**
	 * 级联获取子节点；并给子节点重新设置level等级
	 * @param childs 存放子节点的列表
	 * @param ids 子节点数组
	 * @param mapOrg 存放父节点的MAP对象
	 */
	private void getCascadeChilds(List<TCOrg> childs, String[] ids, Map<String, TCOrg> mapOrg) {
		if(CollectionUtils.isEmpty(childs)) {
			childs = new ArrayList<TCOrg>();
		}
		List<TCOrg> tmps = super.finds(Cnd.where(Exp.in("parentId", ids)));
		if(CollectionUtils.isNotEmpty(tmps)) {
			int size = tmps.size();
			ids = new String[size];
			Map<String, TCOrg> newMapOrg = new HashMap<String, TCOrg>();
			TCOrg tmp = null;
			TCOrg parentTmp = null;
			for (int i=0 ; i<size; i++) {
				tmp = tmps.get(i);
				ids[i] = tmp.getId();
				parentTmp = mapOrg.get(tmp.getParentId());
				tmp.setLevel(parentTmp.getLevel()+1);
				tmp.setSerialName(parentTmp.getSerialName()+IWebConstant.SERVIAL_NAME_SPLIT+tmp.getName());
				tmp.setSerialCode(parentTmp.getSerialCode()+tmp.getId()+IWebConstant.SERVIAL_CODE_SPLIT);
				newMapOrg.put(tmp.getId(), tmp);
			}
			mapOrg = null;
			childs.addAll(tmps);
			getCascadeChilds(childs, ids, newMapOrg);
		}
	}

	@Override
	public PKStringDao<TCOrg> getDao() {
		return (PKStringDao<TCOrg>) dao;
	}
	
}
